package com.kaili.basic.controller;

import com.baomidou.mybatisplus.plugins.Page;
import com.kaili.basic.pojo.dto.*;
import com.kaili.basic.pojo.entity.BaseCompany;
import com.kaili.basic.service.BaseUserService;
import com.kaili.basic.version.ApiVersion;
import com.kaili.common.pojo.entity.BaseUser;
import com.kaili.common.response.CommonStatus;
import com.kaili.common.response.RestStatus;
import com.kaili.common.tenant.DbContextHolder;
import com.kaili.common.util.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.session.SessionInformation;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.UUID;


@ApiVersion(1)
@RequestMapping("/{api_version}")
@RestController
@Api(tags = "用户管理", description = "用户管理相关API")
public class BaseUserController {
    @Autowired
    BaseUserService baseUserService;

    @Bean
    public SessionRegistry getSessionRegistry(){
        SessionRegistry sessionRegistry=new SessionRegistryImpl();
        return sessionRegistry;
    }

    @GetMapping("user/{baseUserId}")
    @ApiOperation(value = "获取用户", notes = "根据用户Id获取一个用户")
    public BaseUser getBaseUserById(@PathVariable Long baseUserId) {
        return baseUserService.getBaseUserById(baseUserId);
    }

    @DeleteMapping("user/{baseUserId}")
    @ApiOperation(value = "删除用户", notes = "根据用户Id删除用户")
    public RestStatus deleteBaseUser(@PathVariable Long[] baseUserId) {
        BaseUser baseUser;
        for(Long va:baseUserId){
            baseUser = baseUserService.getBaseUserById(va);
//            baseUser.setEnabled(false);
//            baseUser.setIsdel(true);
//            baseUserService.updateBaseUser(baseUser);
            invalidateSession(baseUser);
            baseUserService.deleteBaseUser(va);
        }
        return CommonStatus.DELETE_OK;
    }

    @PutMapping(value = "user")
    @ApiOperation(value = "修改用户", notes = "根据用户Id修改用户")
    public RestStatus updateBaseUser(@Validated @RequestBody ValidList<BaseUserUpdateUsersDto> baseUserUpdateUsersDtos) {
        for(BaseUserUpdateUsersDto baseUserUpdateUsersDto:baseUserUpdateUsersDtos){
            BaseUser baseUser = new BaseUser();
            baseUser.setId(baseUserUpdateUsersDto.getId());
            baseUser.setEmployeeId(baseUserUpdateUsersDto.getEmployeeId());
            baseUser.setUsername(baseUserUpdateUsersDto.getUsername());
            baseUser.setPassword(baseUserUpdateUsersDto.getPassword());
            baseUser.setRids(baseUserUpdateUsersDto.getRids());
            baseUser.setEnabled(true);
            BaseUser baseUser1 = baseUserService.getBaseUserById(baseUser.getId().longValue());
            if(baseUser1.getEmployeeId().equals(baseUser.getEmployeeId())) {
                String pwd = baseUser.getPassword();//密码
                String npwd = baseUser.getPassword();//用来循环的密码；
                String encode = hexpwd(pwd, npwd);
                baseUser.setPassword(encode);
                baseUser.setModifyTime(new Date());
                baseUser.setModifyBy(LoginDetailUtils.getCurrentEmployeeId().longValue());
                if (baseUserService.updateBaseUser(baseUser) != -1) {
                    BaseUserUpdateBaseRolesDto baseUserUpdateBaseRolesDto = new BaseUserUpdateBaseRolesDto();
                    baseUserUpdateBaseRolesDto.setId(baseUser.getId());
                    baseUserUpdateBaseRolesDto.setRids(baseUser.getRids());
                    updateBaseUserBaseRoles(baseUserUpdateBaseRolesDto);
                    if (!baseUser.isEnabled()) {
                        invalidateSession(baseUser);
                    }
                } else {
                    return CommonStatus.USER_NAME_REPEAT;
                }
            }else{
                if(baseUserService.getBaseUsersByEmployeeId(baseUser.getEmployeeId())==0){
                    String pwd = baseUser.getPassword();//密码
                    String npwd = baseUser.getPassword();//用来循环的密码；
                    String encode = hexpwd(pwd, npwd);
                    baseUser.setPassword(encode);
                    baseUser.setModifyTime(new Date());
                    baseUser.setModifyBy(LoginDetailUtils.getCurrentEmployeeId().longValue());
                    if (baseUserService.updateBaseUser(baseUser) != -1) {
                        BaseUserUpdateBaseRolesDto baseUserUpdateBaseRolesDto = new BaseUserUpdateBaseRolesDto();
                        baseUserUpdateBaseRolesDto.setId(baseUser.getId());
                        baseUserUpdateBaseRolesDto.setRids(baseUser.getRids());
                        updateBaseUserBaseRoles(baseUserUpdateBaseRolesDto);
                        if (!baseUser.isEnabled()) {
                            invalidateSession(baseUser);
                        }
                    } else {
                        return CommonStatus.USER_NAME_REPEAT;
                    }
                }else{
                    return CommonStatus.E_EXSIT;
                }
            }
        }
        return CommonStatus.UPDATE_OK;
    }

    @PutMapping(value = "user/role")
    @ApiOperation(value = "用户分配角色", notes = "用户分配角色（新增修改都适用）")
    public RestStatus updateBaseUserBaseRoles(@RequestBody BaseUserUpdateBaseRolesDto baseUserUpdateBaseRolesDto) {
        baseUserService.updateBaseUserBaseRoles(baseUserUpdateBaseRolesDto.getId().longValue(), baseUserUpdateBaseRolesDto.getRids());
        return CommonStatus.UPDATE_OK;
    }

    @GetMapping("users")
    @ApiOperation(value = "查询用户", notes = "根据条件查询用户列表")
    public Page<BaseUser> getBaseUsersByKeywords(@ModelAttribute BaseUser baseUser) {
        if(LoginDetailUtils.getSiteId()!=1)
            baseUser.setSiteId(LoginDetailUtils.getSiteId());
        return baseUserService.getBaseUsersByKeywords(new Page<BaseUser>(baseUser.getPage(), baseUser.getPageSize()), baseUser);
    }

    @PutMapping(value = "user/password")
    @ApiOperation(value = "修改密码", notes = "修改密码")
    public RestStatus updatePassWord(@Validated @RequestBody BaseUserUpdatePassWordDto baseUserUpdatePassWordDto) {
        BaseUser user = new BaseUser();
        user.setId(baseUserUpdatePassWordDto.getId());
        user.setUsername(baseUserUpdatePassWordDto.getUsername());
        user.setPassword(baseUserUpdatePassWordDto.getPassword());
        if(baseUserService.baseUserReg(user,1)==-1){
            return CommonStatus.UNAMEORPWORD_NOTEXSIT;
        }
        return CommonStatus.UPDATE_OK;
    }

    @PutMapping(value = "user/resetPassWord")
    @ApiOperation(value = "重置密码", notes = "重置密码")
    public RestStatus resetPassWord(@RequestBody BaseUserResetPassWordDto baseUserResetPassWordDto) {
        BaseUser user = new BaseUser();
        user.setId(baseUserResetPassWordDto.getId());
        user.setUsername(baseUserResetPassWordDto.getUsername());
        user.setPassword("666666");
        if(baseUserService.baseUserReg(user,2)==-1){
            return CommonStatus.UNAMEORPWORD_NOTEXSIT;
        }
        return CommonStatus.UPDATE_OK;
    }

    @PutMapping(value = "user/validatePassWord")
    @ApiOperation(value = "验证密码", notes = "验证密码")
    public RestStatus validatePassWord(@RequestBody BaseUserValidatePassWordDto baseUserValidatePassWordDto) {
        BaseUser user = new BaseUser();
        user.setPassword(baseUserValidatePassWordDto.getPassword());
        user.setUsername(baseUserValidatePassWordDto.getUsername());
        if(baseUserService.baseUserReg2(user)==-1){
            return CommonStatus.UNAMEORPWORD_NOTEXSIT;
        }
        return CommonStatus.VALIDATE_OK;
    }

    @GetMapping(value = "user/relieveUnlock/{name}")
    @ApiOperation(value = "解除锁定", notes = "解除锁定")
    public RestStatus relieveUnlock(@PathVariable String name) {
        baseUserService.relieveUnlock(name);
        System.out.println(LoginDetailUtils.getCompanyCode());
        baseUserService.saveTranslate(name + LoginDetailUtils.getCompanyCode(), 0);
        return CommonStatus.RENOVE_LOCK ;
    }


    @PostMapping(value = "user/addUser")
    @ApiOperation(value = "新增用户", notes = "新增用户")
    public RestStatus addUser(@Validated @RequestBody BaseUserAddUserDto baseUserAddUserDto) {
        BaseUser user = new BaseUser();
        user.setPassword(baseUserAddUserDto.getPassword());
        user.setUsername(baseUserAddUserDto.getUsername());
        user.setEmployeeId(baseUserAddUserDto.getEmployeeId());
        user.setCompanyId(baseUserAddUserDto.getCompanyId());
        user.setRids(baseUserAddUserDto.getRids());
        //判断用户是否超过系统设置用户
        Integer count=baseUserService.selectCountAccount();//已创建用户
        //查询公司能用多少用户
        BaseCompany baseCompany=userCount();
        if(count<=baseCompany.getUserCount()){
            if(baseUserService.getBaseUsersByEmployeeId(user.getEmployeeId())==0) {
                user.setCreateTime(new Date());
                user.setCreateBy(LoginDetailUtils.getCurrentEmployeeId().longValue());
               /* BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
                String encode = encoder.encode(user.getPassword());*/
                String pwd = user.getPassword();//密码
                String npwd = user.getPassword();//用来循环的密码；
                String encode = hexpwd(pwd, npwd);
                user.setPassword(encode);
                if (baseUserService.addUser(user) != -1) {
                    BaseUserUpdateBaseRolesDto baseUserUpdateBaseRolesDto = new BaseUserUpdateBaseRolesDto();
                    baseUserUpdateBaseRolesDto.setId(user.getId());
                    baseUserUpdateBaseRolesDto.setRids(user.getRids());
                    updateBaseUserBaseRoles(baseUserUpdateBaseRolesDto);
                } else {
                    return CommonStatus.USER_NAME_REPEAT;
                }
                return CommonStatus.ADD_OK;
            }else{
                return CommonStatus.E_EXSIT;
            }
          }else{
            return CommonStatus.BIG_COUNT;
        }

    }

    /**
     * 清session
     * @param user
     */
    private void invalidateSession(BaseUser user){
        List<Object> o= getSessionRegistry().getAllPrincipals();
        for (Object principal : o) {
            if (principal instanceof BaseUser) {
                final BaseUser loggedUser = (BaseUser) principal;
                if (user.getUsername().equals(loggedUser.getUsername())) {
                    List<SessionInformation> sessionsInfo = getSessionRegistry().getAllSessions(principal, false);
                    if (null != sessionsInfo && sessionsInfo.size() > 0) {
                        for (SessionInformation sessionInformation : sessionsInfo) {
                            sessionInformation.expireNow();
                        }
                    }
                }
            }
        }
    }

    //查询主库公司是能创建多少用户
    public BaseCompany  userCount(){
        String currentDbType = DbContextHolder.getDbType();
        DbContextHolder.setDbType(CommonConstant.MAIN_DB_READ);
        BaseCompany baseCompany=baseUserService.selectMapCompany(LoginDetailUtils.getCompanyCode());//可创建用户
        DbContextHolder.setDbType(currentDbType);
        return baseCompany;
    }

    public String hexpwd(String pwd, String npwd) {
        String salt = UUID.randomUUID().toString().substring(0, 6);
        System.out.println(SHA256Util.getSHA256StrJava("G1" + salt + pwd).length());//G1+随机数+密码进行SHA256运算
        Random random = new Random();
        int cycletimes = (int) (random.nextInt(100)) + 100;//后随机数范围变成[ 100~999）；循环次数
        System.out.println(cycletimes);
        String sh256 = "";
        sh256 = SHA256Util.getSHA256StrJava("G1" + salt + pwd);//G1+随机数+密码进行SHA256运算 循环多少次循环的次数是随机生成的
        for (int i = 0; i <= cycletimes; i++) {
            sh256 = SHA256Util.getSHA256StrJava("G1" + salt + pwd + sh256);//G1+随机数+密码进行SHA256运算 循环多少次循环的次数是随机生成的
            sh256 = sh256;
            //sh256=SHA256Util.getSHA256StrJava("G1"+cd+"123456");
            //System.out.println(sh256);
        }
        System.out.println(sh256);
        String hex = HexStringUtils.toHex("G1" + salt + cycletimes + sh256);//16进制字符串
        System.out.println("16进制字符串存数据库" + hex);
        return hex;
    }
}
